#include "iConfig.hpp"
#include <glf/task/taskCondition.h>
#include <glf/task/taskManager.h>
#include <glf/core/timer.h>

namespace glf {

TaskCondition::TaskCondition()
	: m_IsActive(true)
	, m_IsWaiting(false)
	, m_Condition(m_Mutex)
	, m_MinimalRunLength(0)
{
	if(m_MinimalRunLength > 0)
	{
		m_WakeUpTime = GetMicroseconds();
	}
}

TaskCondition::~TaskCondition()
{
}

bool TaskCondition::Signal()
{
	LockScope lock(m_Mutex);

	if(m_IsWaiting)
	{
		m_IsWaiting = false;
		m_Condition.Signal();
		return true;
	}
	else
	{
		return false;
	}
}

void TaskCondition::AddTaskManager(TaskManager* tm)
{
	m_TaskManagerList.push_back(tm);
	tm->StartWork();
}

void TaskCondition::RemoveTaskManager(TaskManager* tm)
{
	m_TaskManagerList.remove(tm);
	tm->EndWork();
}

void TaskCondition::Stop()
{
	m_IsActive = false;
	Signal();
}

void TaskCondition::Wait()
{
	if(m_IsActive == false)
	{
		return;
	}

	do 
	{
		for(TaskManagerList::iterator i = m_TaskManagerList.begin(),
				end = m_TaskManagerList.end();
			i != end;
			++i)
		{
			if((*i)->HasPendingTask())
			{
				return;
			}
		}

		if(m_MinimalRunLength == 0)
		{
			break;
		}
			
	} while (m_WakeUpTime + m_MinimalRunLength > GetMicroseconds());
	
	// Decrease their working state
	for(TaskManagerList::iterator i = m_TaskManagerList.begin(),
			end = m_TaskManagerList.end();
		i != end;
		++i)
	{
		(*i)->EndWork();
	}

	
	m_Mutex.Lock();
	m_IsWaiting = true;
	m_Condition.Wait(0);
	m_Mutex.Unlock();
	
	if(m_MinimalRunLength != 0)
	{
		m_WakeUpTime = GetMicroseconds();
	}
	
	
	// Increase their working state
	for(TaskManagerList::iterator i = m_TaskManagerList.begin(),
			end = m_TaskManagerList.end();
		i != end;
		++i)
	{
		(*i)->StartWork();
	}
}

} // end namespace glf
